import net.yiny.scrummer.ui.storyboard.CardBuilder

def builder = new CardBuilder()
def panel = null

before_each 'initialise the builder and get the panel it creates', {
    panel = builder.initialise()
}

scenario 'initialisation of the builder should result in a non-null panel', {
    when 'we initialise the builder'
    then 'it should return a non-null panel', {
        panel.shouldNotBe null
    }
}

scenario 'setting the name property on the builder should change the value of the name text field', {
    def name
    given 'that we have a reference to the text field name component in the panel', {
        name = findChildComponent(panel, 'JTextField', 'name')
    }
    then 'that reference should be non-null', {
        name.shouldNotBe null
    }
    and 'it should be disabled and empty', {
        assertProperties name, ['enabled': false, 'editable': false, 'text': '']
    }
    when 'we set the name property on the builder', {
        builder.name = 'Test Name'
    }
    then 'it should have the same value in the component', {
        assertProperties name, ['text': 'Test Name']
    }
}

scenario 'setting the id property on the builder should change the value of the id text field', {
    def id
    given 'that we have a reference to a text field id component in the panel', {
        id = findChildComponent(panel, 'JTextField', 'id')
    }
    then 'that reference should not be null', {
        id.shouldNotBe null
    }
    and 'it should be disabled and empty', {
        assertProperties id, ['enabled': false, 'editable': false, 'text': '']
    }
    when 'we set the id property on the builder', {
        builder.id = '#100'
    }
    then 'it should have the same value in the component', {
        assertProperties id, ['text': '#100']
    }
}

scenario 'setting the description property on the builder should change the value of the description text area', {
    def desc
    given 'that we have a reference to the text area description component in the panel', {
        desc = findChildComponent(panel, 'JTextArea', 'description')
    }
    then 'that reference should not be null', {
        desc.shouldNotBe null
    }
    and 'it should be disabled and empty', {
        assertProperties desc, ['enabled': false, 'editable': false, 'text': '']
    }
    when 'we set the description property on the builder', {
        builder.description = 'Test Description'
    }
    then 'it should have the same value in the component', {
        assertProperties desc, ['text': 'Test Description']
    }
}

def assertProperties(component, props) {
    props.each {
        component.properties[it.key].shouldBeEqualTo it.value
    }
}

def findChildComponent(panel, type, name) {
    def findComponent
    def components = []
    findComponent = {component, in_type, in_name ->
        if (component.name == in_name && component.getClass().name.endsWith(in_type)) {
            components += component
        }
        else if (component instanceof java.awt.Container) {
            component.components.each({
                findComponent(it, in_type, in_name)
            })
        }
    }
    findComponent(panel, type, name)
    if (components.size > 1) {
        throw new IllegalStateException("Found more than one component with name $name and type $type")
    }
    else return components.size() == 1 ? components[0] : null
}

